package com.ruoyi.framework.security.dingtalk;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.dingtalk.service.DdUserService;
import com.ruoyi.dingtalk.service.DingTalkApiService;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.web.authentication.CustWebAuthenticationDetailsSource;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

@Slf4j
@Configuration
public class DingTalkLoginConfig {

    private TokenService tokenService;
    private ObjectMapper objectMapper;
    private DingTalkApiService dingTalkApiService;
    private ISysConfigService iSysConfigService;
    private DdUserService ddUserService;
    private UserDetailsService userDetailsService;
    private ISysUserService iSysUserService;

    @Autowired
    public void setTokenService(TokenService tokenService) {
        this.tokenService = tokenService;
    }

    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Autowired
    public void setiSysUserService(ISysUserService iSysUserService) {
        this.iSysUserService = iSysUserService;
    }

    @Autowired
    public void setDdUserService(DdUserService ddUserService) {
        this.ddUserService = ddUserService;
    }

    @Autowired
    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Autowired
    public void setiSysConfigService(ISysConfigService iSysConfigService) {
        this.iSysConfigService = iSysConfigService;
    }

    @Autowired
    public void setDingTalkApiService(DingTalkApiService dingTalkApiService) {
        this.dingTalkApiService = dingTalkApiService;
    }

    public DingTalkLoginAuthenticationFilter dingTalkLoginAuthenticationFilter(HttpSecurity httpSecurity) {
        RequestMatcher requestMatcher = new AntPathRequestMatcher("/dingTalk/loginByDingTalk", null);
        DingTalkLoginAuthenticationFilter dingTalkLoginAuthenticationFilter = new DingTalkLoginAuthenticationFilter(requestMatcher);
        dingTalkLoginAuthenticationFilter.setDingTalkApiService(dingTalkApiService);
        dingTalkLoginAuthenticationFilter.setDdUserService(ddUserService);
        dingTalkLoginAuthenticationFilter.setISysConfigService(iSysConfigService);
        dingTalkLoginAuthenticationFilter.setUserDetailsService(userDetailsService);
        dingTalkLoginAuthenticationFilter.setAuthenticationDetailsSource(new CustWebAuthenticationDetailsSource());
        dingTalkLoginAuthenticationFilter.setSessionAuthenticationStrategy((authentication, request, response) -> {
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userDetails.getUsername(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
            LoginUser loginUser = (LoginUser) authentication.getPrincipal();
            iSysUserService.recordLoginInfo(loginUser.getUserId());
            String token = tokenService.createToken(loginUser);
            request.setAttribute("DING_TALK_SESSION_ID", token);
        });
        //登录成功处理类
        dingTalkLoginAuthenticationFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            String dingTalkSessionId = (String) request.getAttribute("DING_TALK_SESSION_ID");
            AjaxResult ajaxResult = AjaxResult.success();
            ajaxResult.put(Constants.TOKEN, dingTalkSessionId);
            String s = objectMapper.writeValueAsString(ajaxResult);
            ServletUtils.renderString(response, s);
        });
        //登录失败处理类
        dingTalkLoginAuthenticationFilter.setAuthenticationFailureHandler((request, response, exception) -> {
            String message = exception.getMessage();
            AjaxResult ajaxResult = AjaxResult.error(message);
            ServletUtils.renderString(response, JSON.toJSONString(ajaxResult));
        });
        return dingTalkLoginAuthenticationFilter;
    }

}
